home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr48 / 386p_200.zip / 386FILE.ASM < prev    next >
Assembly Source File  |  1995-01-12  |  13KB  |  447 lines

  1.         
  2.         .386p
  3. code32 segment para public use32
  4.        assume cs:code32,ds:code32
  5.  
  6. include 386power.inc
  7.         align byte
  8.  
  9. ; This module uses the space between
  10. ; _LoMemBase and lomemtop for buffering file transferts to extended memory
  11.  
  12.  
  13. fname_buf db 256 dup(0) ; buffer fo filename
  14.  
  15. ; _FOpen: Opens a file and returns its handle into V86bx
  16. ; In:
  17. ;   ESI -> ASCIIZ filename max. 255 bytes long 
  18. ;   AL  == file mode: 00 = Read Only
  19. ;                     01 = Write Only (create it if it doesn't exist)
  20. ; Out:
  21. ;   if  carry set then
  22. ;       Error opening file
  23. ;   else
  24. ;       File opened succesfully
  25. ;              V86bx = file handle
  26.  
  27.         public _FOpen
  28. _FOpen:
  29.         pushad
  30.  
  31.         mov ebp,eax
  32.  
  33.         mov cl,1
  34.         mov edi,offset fname_buf
  35. zerother:        
  36.         lodsb
  37.         inc cl ; when 255 is reached, this will be resetted
  38.         je  topped
  39.         stosb
  40.         or al,al
  41.         jne zerother
  42. topped: mov esi,offset fname_buf
  43.         mov byte ptr [edi],0 ;put a NUL for safety
  44.         add esi,_Code32Base ; get a linear address
  45.         mov ecx,esi 
  46.         mov V86cx,0 ; clear all file attributes OR access mask
  47.         shr esi,4  ; segment into dx
  48.         and ecx,0fh ; offset  into cx
  49.         mov eax,ebp ; get eax back
  50.         mov V86ax,3D00h
  51.         cmp al,00
  52.         je  gopenr         ; al=00 --> open to read
  53.         mov V86ax,3C01h    ; else  --> open to write
  54. gopenr:        
  55.         mov V86dx,cx  ; send seg:ofs
  56.         mov V86ds,si  ;
  57.         mov al,21h    ; select interrupt
  58.         call _ExecINT       ; go V86
  59.         mov ax,V86ax  ;
  60.         mov V86bx,ax  ; copy handle to V86bx
  61.         popad
  62.         ret
  63.         
  64. ; _FClose Closes file with handle V86bx
  65. ; In:
  66. ;   V86bx = file handle
  67.         public _FClose
  68. _FClose:
  69.         push eax
  70.         mov V86ax,3e00h
  71.         mov al,21h
  72.         call _ExecINT
  73.         pop eax
  74.         ret
  75.  
  76.  
  77. public  _FSeek
  78.  
  79. ; _FSeek Seek position in file
  80. ; In:
  81. ;   V86bx = file handle
  82. ;   EAX   = signed offset to move to
  83. ;   DL    = from: 0-beginning of file, 1-current location, 2-end of file
  84. ; Out:
  85. ;   If carry clear then Seek done
  86. ;               EAX = new offset from beginning of file
  87. ;   else EAX trashed
  88.  
  89. _FSeek: 
  90.         push edx
  91.         mov V86ah,42h
  92.         mov V86al,dl
  93.         mov V86dx,ax
  94.         shr eax,16
  95.         mov V86cx,ax
  96.         mov al,21h
  97.         call _ExecINT
  98.         jc fserr
  99.         mov ax,V86dx
  100.         shl eax,16
  101.         mov ax,V86ax
  102. fserr:
  103.         pop edx
  104.         ret
  105.  
  106. public  _FSize
  107.  
  108. ; _FSize Get size of file
  109. ; In:
  110. ;   V86bx = file handle
  111. ; Out:
  112. ;   if Carry Clear then  File exist
  113. ;                        EAX = size of file
  114. ;   else error, EAX trashed
  115.  
  116. _FSize: push edx
  117.         mov dl,01h  ; get current file position
  118.         xor eax,eax ;    
  119.         call _FSeek ;
  120.         push eax     ; save current file position
  121.         
  122.         mov dl,02    ;  seek to end of file
  123.         xor eax,eax  ;
  124.         call _FSeek  ;
  125.         
  126.         pop edx ; restore current file position
  127.         
  128.         push eax ; save file lenght
  129.         
  130.         mov eax,edx  ; restore file pointer
  131.         mov dl,00    ;
  132.         call _FSeek  ;
  133.         
  134.         pop eax  ; restore result
  135.         ; EAX = FILE SIZE
  136.         pop edx
  137.         ret
  138.  
  139. ; _FRead Reads a block from a file with handle V86bx
  140. ; In:   V86bx = file handle
  141. ;       EDI   = base address of block ( relative offset) 
  142. ;               into extended memory
  143. ;       EAX   = size of block 
  144. ; Out:  If carry clear
  145. ; N.B.  The space between _LoMemBase and _LoMemTop is used as a 
  146. ;       "transition buffer"  if EDI points into extended memory
  147.  
  148.         public _FRead
  149. _FRead: 
  150.         pushad
  151.         mov ebp,_LoMemBase
  152.         mov edx,eax          ; copy into EDX size of block to read
  153.         mov ebx,_LoMemTop  ;
  154.  
  155.         cmp edi,ebp        ;
  156.         jb @nouppa         ; low memory destination, write directly to it
  157.         ; high memory destination, use low memory as a buffer
  158.         mov ecx,0FFE0h ; make sure we don't have false wraps
  159.         sub ebx,_LoMemBase ;
  160.         and bl,cl          ; get free low memory (paragraph aligned)
  161.         cmp ebx,ecx
  162.         jb @rsmall
  163.         mov ebx,ecx ; read 0FFF0 bytes a time
  164. @rsmall:    ; ebx = size of buffer in low memory
  165.         add ebp,_Code32Base ; convert to linear address
  166. @rchunk:
  167.         cmp ebx,edx    
  168.         jb @rfittrans ; if (bytes_to_read > buffer) then read another chunk
  169.         mov ebx,edx    ; else this is the last chunk, make it fit
  170. @rfittrans: ; ebx = size of chunk to read
  171.  
  172.         mov esi,ebp  ; convert linear address to seg:ofs
  173.         mov ecx,ebp  ;
  174.         shr esi,4    ;
  175.         and ecx,0Fh  ;
  176.         mov V86ds,si ;
  177.         mov V86dx,cx ;
  178.         
  179.         mov V86cx,bx ; chunk size
  180.         
  181.         mov V86ah,3fh ; read chunk
  182.         mov al,21h    ;
  183.         call _ExecINT       ;
  184.         jc @rfloaderr        ; get out if error
  185.         
  186.         mov esi,_LoMemBase    ;
  187.         mov ecx,ebx           ; move up this chunk
  188.         rep movsb             ;
  189.         sub edx,ebx      ; update counter of bytes to read    
  190.         jne @rchunk   ; end of block ?  if not at the end, read next chunk 
  191.         clc ; say, no error
  192. @rfloaderr:
  193.         popad
  194.         ret    
  195. @rflucked:
  196.         stc ; say, error
  197.         popad
  198.         ret
  199.         
  200. @nouppa: ; load into low memory       
  201.         mov edx,eax
  202.         mov ebx,0FFF0h
  203.         ; get linear address
  204.         mov ebp,edi
  205.         add ebp,_Code32Base
  206. @lrchunk:
  207.         cmp ebx,edx    
  208.         jbe @lrfittrans ; if (bytes_to_read > buffer) then read another chunk 
  209.         mov ebx,edx    ; else this is the last chunk, make it fit
  210. @lrfittrans: ; ebx = size of chunk to read
  211.  
  212.         mov esi,ebp  ; convert linear address to seg:ofs
  213.         mov ecx,ebp  ;
  214.         shr esi,4    ;
  215.         mov V86ds,si ;
  216.         and ecx,0Fh  ;
  217.         mov V86dx,cx ;
  218.         
  219.         mov V86cx,bx ; chunk size
  220.         
  221.         mov V86ah,3fh ; read chunk
  222.         mov al,21h    ;
  223.         call _ExecINT       ;
  224.         jc @lrfloaderr        ; get out if error
  225.         add ebp,ebx      ; move forward the linear pointer
  226.         sub edx,ebx      ; update counter of bytes to read    
  227.         jne @lrchunk   ; end of block ?  if not at the end, read next chunk 
  228.         clc ; say, no error
  229. @lrfloaderr:
  230.         popad
  231.         ret    
  232.  
  233. ; standard 386file error messages
  234.  
  235. eropen db 'ERROR WHILE OPENING FILE TO READ FROM',CR,LF,CR,LF,'$'
  236. ewopen db 'ERROR WHILE OPENING FILE TO WRITE TO',CR,LF,CR,LF,'$'
  237. eracc  db 'ERROR WHILE READING FROM FILE',CR,LF,CR,LF,'$'
  238. ewacc  db 'ERROR WHILE WRITING TO FILE',CR,LF,CR,LF,'$'        
  239.  
  240. ; _FLoad Loads a file with ASCIIZ name pointed by DS:ESI (max 255 bytes)
  241. ; Out:  If carry clear
  242. ;       EAX = file size
  243. ;       The file gets loaded starting from _HiMemBase
  244. ;       The space between _LoMemBase and _LoMemTop is used as a 
  245. ;       "transition buffer"
  246. ;       N.B. _LoMemBase and _HiMemBase are left as they were
  247. ;            BEFORE calling _FLoad, what will you do with the heaps
  248. ;            is up to you ( you can update them using the file size
  249. ;            or simply do nothing and "discard" the loaded data ).
  250. ;       Why use extended mem instead of dos mem ? Because dos mem
  251. ;       is precious, it's the only place where you can put things directly
  252. ;       accessible in 'real' and protected mode.
  253.  
  254.         public _FLoad
  255. _FLoad: ; ds:esi = ptr to ASCIIZ file name
  256.         push edi
  257.         push ebp
  258.         mov al,0 ; read from file
  259.         mov _386Return,offset eropen
  260.         call _FOpen
  261.         jc @flucked ; Oops! Cannot open file
  262.         call _FSize
  263.         jc @flucked ; Oops! Seek problems
  264.         mov _386Return,offset eracc
  265.         mov edi,_HiMemBase ; Is there enough free space in high memory ?
  266.         mov ebp,_HiMemTop  ;
  267.         sub ebp,edi        ;
  268.         cmp eax,ebp        ;
  269.         jnbe @flucked ; Oops! File too big
  270.         call _FRead
  271.         jc @floaderr
  272.         mov _386Return, offset _386Terminator
  273.         call _FClose  ; hasta la vista, baby
  274.         clc
  275. @floaderr:
  276.         pop ebp
  277.         pop edi
  278.         ret
  279. @flucked:
  280.         pop ebp
  281.         pop edi
  282.         stc
  283.         ret
  284.         
  285. ; _LoFLoad 
  286. ;       Loads a file with ASCIIZ name pointed by DS:ESI (max 255 bytes)
  287. ; Out:  If carry clear
  288. ;       EAX = file size
  289. ;       The file gets loaded starting from _LoMemBase
  290. ;       Use this to directly load things into dos memory
  291.  
  292.         public _LoFLoad
  293. _LoFLoad: ; ds:esi = ptr to ASCIIZ file name
  294.         push edi
  295.         push ebp
  296.         mov _386Return,offset eropen
  297.         mov al,0 ; read from file
  298.         call _FOpen
  299.         jc @flucked ; Oops! Cannot open file
  300.         call _FSize
  301.         jc @flucked ; Oops! Seek problems
  302.         mov _386Return,offset eracc
  303.         mov edi,_LoMemBase
  304.         mov ebp,_LoMemTop
  305.         sub ebp,edi
  306.         cmp eax,ebp  
  307.         ja @flucked ; Oops! File too big
  308.         call _FRead
  309.         jc @lfloaderr
  310.         mov _386Return,offset  _386Terminator
  311.         call _FClose  ; hasta la vista, baby
  312.         clc
  313. @lfloaderr:
  314.         pop ebp
  315.         pop edi
  316.         ret
  317.         
  318. ; _FWrite Writes a block of memory to file with handle V86bx
  319. ; In:   V86bx = file handle
  320. ;       esi   = buffer base (relative address)
  321. ;       eax   = file size
  322. ; Out:  If carry clear
  323. ;       file write done
  324.  
  325.         public _FWrite
  326. _FWrite:
  327.         pushad 
  328.         mov edx,eax ; edx = counter of bytes to move
  329.         mov ebp,(640*1024)   ;
  330.         sub ebp,_Code32Base  ; code32-relative offset of top 640k
  331.         cmp esi,ebp   ; is source block under the 640k dos limit ?
  332.         jb @writedirect
  333.         
  334.         mov ebp,_LoMemBase
  335.         
  336.         mov ecx,0FFF0h       ;max. transfert buffer (paragraph aligned)
  337.         
  338.         mov ebx,_LoMemTop    ;
  339.         sub ebx,ebp          ; available low memory
  340.         
  341.         and bl,cl            ; paragraph align
  342.         
  343.         cmp ebx,ecx          ; put into ebx the smallest 
  344.         jb @wfull            ;
  345.         mov ebx,ecx          ;
  346.         
  347. @wfull:   ; ebx = size of transfert buffer
  348.         add ebp,_Code32Base     ; LINEAR address of _LoMemBase
  349. @wchunk:
  350.         cmp ebx,edx            ;
  351.         jbe @wafittrans        ;
  352.         mov ebx,edx            ; if this is the last chunk, make it fit
  353. @wafittrans: ;  ebx = bytes to move this time
  354.  
  355.         mov edi,_LoMemBase ;
  356.         mov ecx,ebx        ;
  357.         rep movsb          ; move DOWN TO LOW DOS MEMORY a chunk
  358.         
  359.         mov edi,ebp     ; linear to seg:ofs
  360.         mov ecx,ebp     ;
  361.         shr edi,4       ;
  362.         mov V86ds,di    ;
  363.         and ecx,0Fh     ;
  364.         mov V86dx,cx    ;
  365.         
  366.         mov V86cx,bx    ;
  367.         mov V86ah,40h   ;
  368.         mov al,21h      ;  translate & write block
  369.         call _ExecINT         ;
  370.         jc @wfsaverr
  371.  
  372.         sub edx,ebx      ;
  373.         jne @wchunk  ; loop if there are other blocks
  374.         popad
  375.         clc
  376.         ret
  377. @wfsaverr:
  378.         popad
  379.         stc
  380.         ret        
  381.  
  382. @writedirect:
  383.         mov edx,eax
  384.         ; edx = size of block
  385.         mov ebx,0FFF0h
  386.         ; ebx = size of transfert buffer
  387.         mov ebp,esi     ; LINEAR address of esi
  388.         add ebp,_Code32Base
  389. @lwchunk:
  390.         cmp ebx,edx             ;
  391.         jbe @lwafittrans        ;
  392.         mov ebx,edx             ; if this is the last chunk, make it fit
  393. @lwafittrans: ;  ebx = bytes to move this time
  394.  
  395.         mov edi,ebp     ; linear to seg:ofs
  396.         mov ecx,ebp     ;
  397.         shr edi,4       ;
  398.         mov V86ds,di    ;
  399.         and ecx,0Fh     ;
  400.         mov V86dx,cx    ;
  401.         
  402.         mov V86cx,bx    ;
  403.         mov V86ah,40h   ;
  404.         mov al,21h      ;  translate & write block
  405.         call _ExecINT         ;
  406.         jc @wfsaverr
  407.         add ebp,ebx     ;
  408.         sub edx,ebx     ;
  409.         jne @lwchunk  ; loop if there are other blocks
  410.         popad
  411.         clc
  412.         ret
  413.         
  414. ; _FSave Saves a block of memory 
  415. ; into the file with ASCIIZ name 
  416. ; In:
  417. ;       esi = ptr to asciiz file name in low memory
  418. ;       edi = buffer base
  419. ;       eax = file size
  420. ; Out:  If carry clear
  421. ;       file write done
  422.  
  423.         public _FSave
  424. _FSave: 
  425.         push esi
  426.         push eax
  427.         mov _386Return,offset  ewopen
  428.         mov al,1
  429.         call _FOpen
  430.         jc @fsaverr
  431.         mov _386Return,offset  ewacc
  432.         mov eax,[esp]; restore block size into eax
  433.         mov esi,edi
  434.         call _FWrite
  435.         jc @fsaverr
  436.         call _FClose
  437.         mov _386Return,offset _386Terminator
  438.         clc
  439. @fsaverr:
  440.         pop eax
  441.         pop esi
  442.         ret
  443.                 
  444. code32  ends
  445.         end
  446.  
  447.